#include <iostream>
#include <utility>

// 右值引用与完美转发是C++11引入的核心特性，核心作用是在函数模板中， 将参数原封动不地转发给其他函数，同时保留参数的左值、右值属性，
// 解决了传统转发中"右值被转为左值"导致的语义丢失问题(如无法触发移动构造、移动赋值)

namespace S1 {
    void process(int& x) {
        std::cout << "处理左值:" << x << std::endl;
    }

    void process(int&& x) {
        std::cout << "处理右值:" << x << std::endl;
    }

    template<typename T>
    void forward_func(T x) {
        process(x); // 不管T是什么类型都是调用的是左值
    }
}

namespace S2 {
    // 完美转发模板函数： 用万能引用接收参数，用std::forward转发
    template<typename T>
    void forward_func(T&& x) { // 万能引用: T&&可接收左值或右值
        S1::process(std::forward<T>(x));  // 完美转发: 保留x的原始属性
    }
}

int main() {
    int a = 10;
    // S1::forward_func(a); // 传入左值
    // S1::forward_func(20); // 传入右值

    // 引用折叠规则
    S2::forward_func(a); // 传入左值 -> T 推导为int&, forward转发为左值 -> 调用process(int&)
    S2::forward_func(20); // 传入右值  -> T 推导为int&&, forward转发为右值  -> 调用process(int&&)
    // 转发被std::move 转换的左值，转为右值
    S2::forward_func(std::move(a)); // std::move 将 a 转为右值 -> T 推导为int, forward 转发为右值 -> process(int&&)

    return 0;
}